package com.fjwt.gz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fjwt.gz.components.mq.constant.WebSocketConstants;
import com.fjwt.gz.components.mq.websocket.server.PCWsChannelServer;
import com.fjwt.gz.components.oss.model.MockMultipartFile;
import com.fjwt.gz.components.oss.model.OssFileConfig;
import com.fjwt.gz.components.oss.service.OssFileService;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.model.security.GzUserDetails;
import com.fjwt.gz.core.third.interfaces.IOfficialService;
import com.fjwt.gz.db.base.BaseAgentApp;
import com.fjwt.gz.db.config.dynamic.WxMpProperties;
import com.fjwt.gz.db.dto.ActivityChannelDTO;
import com.fjwt.gz.db.entity.*;
import com.fjwt.gz.db.vo.ActivityChannelVO;
import com.fjwt.gz.db.vo.AgentAppVO;
import com.fjwt.gz.service.mapper.ActivityChannelMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjwt.gz.util.GeoValidator;
import com.fjwt.gz.util.Utils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 活动公众号渠道表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-04-09
 */
@Slf4j
@Service
public class ActivityChannelService extends ServiceImpl<ActivityChannelMapper, ActivityChannelEntity> {


    @Autowired
    private ActivityChannelMapper activityChannelMapper;

    @Autowired
    private OssRecordService ossRecordService;

    @Autowired
    private AgentInfoService agentInfoService;

    @Autowired
    private MchInfoService mchInfoService;

    @Resource
    private AgentEmployeeService agentEmployeeService;

    @Autowired
    private ActivityService activityService;

    @Autowired
    private AgentAppService agentAppService;

    @Autowired
    private IOfficialService officialService;

    @Autowired
    private OssFileService ossFileService;

    @Autowired
    private PCWsChannelServer wsChannelServer;


    /**
     * 活动渠道码列表
     *
     * @param iPage
     * @param activityChannelDTO
     * @return
     */
    public IPage<ActivityChannelVO> getChannelList(IPage iPage, ActivityChannelDTO activityChannelDTO) {
        IPage<ActivityChannelVO> list = activityChannelMapper.list(iPage, activityChannelDTO);
        return list;
    }


    /**
     * 获取导出渠道码列表
     */
    public List<ActivityChannelVO> allList(ActivityChannelDTO activityChannelDTO) {
        activityChannelDTO.setIsDeleted(0);
        List<ActivityChannelVO> list = activityChannelMapper.list(activityChannelDTO);
        Set<String> agentNos = getAgentNos(list);
        if (!agentNos.isEmpty()) {
            // 查询所属地区名称
            List<AgentInfoEntity> agentInfoList = agentInfoService.listByIds(agentNos);

            Map<String, String> agentNameMap = agentInfoList.stream()
                    .collect(Collectors.toMap(AgentInfoEntity::getAgentNo, AgentInfoEntity::getAgentName));

            for (ActivityChannelVO activityChannelVO : list) {
                List<String> agentNameList = new ArrayList<>();
                agentNameList.add(agentNameMap.getOrDefault(activityChannelVO.getAgentNo2(), "其他"));
                agentNameList.add(agentNameMap.getOrDefault(activityChannelVO.getAgentNo3(), "其他"));
                agentNameList.add(agentNameMap.getOrDefault(activityChannelVO.getAgentNo4(), "其他"));
                activityChannelVO.setAgentNameList(agentNameList);
            }
        }
        log.info("导出渠道码列表返回数据：{}", JSONUtil.toJsonStr(list));
        return list;
    }

    /**
     * 获取渠道码机构号
     */
    private static Set<String> getAgentNos(List<ActivityChannelVO> list) {
        Set<String> agentNos = new HashSet<>();
        if (CollUtil.isEmpty(list)) {
            return agentNos;
        }
        for (ActivityChannelVO activityChannelVO : list) {
            String agentNo2 = activityChannelVO.getAgentNo2();
            if (agentNo2 != null) {
                agentNos.add(agentNo2);
            }
            String agentNo3 = activityChannelVO.getAgentNo3();
            if (agentNo3 != null) {
                agentNos.add(agentNo3);
            }
            String agentNo4 = activityChannelVO.getAgentNo4();
            if (agentNo4 != null) {
                agentNos.add(agentNo4);
            }
        }
        return agentNos;
    }


    /**
     * 批量新增渠道码
     */
    @Transactional
    public JSONObject addByBatch(ActivityChannelDTO activityChannelDTO, String bizType) {
        // 校验参数
        if (StrUtil.isBlank(activityChannelDTO.getOssFileUrl()) || ObjectUtils.isEmpty(activityChannelDTO.getChannelType())
                || StrUtil.isBlank(activityChannelDTO.getAppId())) {
            throw new BizException("请求参数异常，请检查！");
        }
        // 查询机构信息
        AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(activityChannelDTO.getAgentNo());
        if (ObjectUtils.isEmpty(agentInfo)) {
            throw new BizException("公众号归属机构不存在");
        }

        // 查询 机构app信息
        List<AgentAppVO> agentNoApp = agentAppService.getAgentNoApp(activityChannelDTO.getAgentNo(), Constants.AGENT_APP_TYPE.WX_OFFICIAL, activityChannelDTO.getAppId());
        if (ObjectUtils.isEmpty(agentNoApp)) {
            throw new BizException("该机构的公众号不存在");
        }

        // 获取文件导入的渠道信息
        List<ActivityChannelDTO.ActivityChannel> activityChannelToList = getActivityChannelToList(activityChannelDTO.getOssFileUrl(),
                activityChannelDTO.getChannelType(), bizType);
        log.info("新增渠道码导入文件数据：{}", JSONUtil.toJsonStr(activityChannelToList));

        // 查询oss上传记录
        LambdaQueryWrapper<OssRecordEntity> ossRecordWrapper = OssRecordEntity.gw();
        ossRecordWrapper.eq(OssRecordEntity::getOssUrl, activityChannelDTO.getOssFileUrl());
        ossRecordWrapper.eq(OssRecordEntity::getUploadType, Constants.OSS_UPLOAD_TYPE.ACTIVITY_CHANNEL_IMPORT);
        OssRecordEntity recordEntity = ossRecordService.getBaseMapper().selectOne(ossRecordWrapper);
        if (Objects.isNull(recordEntity)) {
            throw new BizException("导入失败！未找到，导入文件");
        }

        // 新增的渠道码和渠道码归属机构并去重
        List<String> channelCodes;
        List<String> agentNo4List;
        if (Constants.CHANNEL_TYPE.ORG_NETWORK != activityChannelDTO.getChannelType()) {
            channelCodes = activityChannelToList.stream().map(item -> item.getAgentNo4() + "-" + item.getChannelCode()).collect(Collectors.toList());
            agentNo4List = activityChannelToList.stream().map(ActivityChannelDTO.ActivityChannel::getAgentNo4).distinct().toList();
        } else {
            channelCodes = activityChannelToList.stream().map(ActivityChannelDTO.ActivityChannel::getChannelCode).collect(Collectors.toList());
            agentNo4List = activityChannelToList.stream().map(ActivityChannelDTO.ActivityChannel::getChannelCode).distinct().toList();
        }

        // 查询已存在的渠道码
        LambdaQueryWrapper<ActivityChannelEntity> queryWrapper = ActivityChannelEntity.gw();
        queryWrapper.in(ActivityChannelEntity::getChannelCode, channelCodes);
        queryWrapper.eq(ActivityChannelEntity::getIsDeleted, Constants.IS_DELETED.NO);
        queryWrapper.eq(ActivityChannelEntity::getChannelType, activityChannelDTO.getChannelType());
        queryWrapper.eq(ActivityChannelEntity::getAppId, activityChannelDTO.getAppId());
        List<ActivityChannelEntity> activityChannelEntityList = activityChannelMapper.selectList(queryWrapper);
        List<String> existChannelCodes = activityChannelEntityList.stream().map(ActivityChannelEntity::getChannelCode).toList();

        channelCodes = activityChannelToList.stream().map(ActivityChannelDTO.ActivityChannel::getChannelCode).collect(Collectors.toList());

        // 查询所填的机构网点是否存在
        List<AgentInfoEntity> agentInfos = this.agentInfoService.getAgentInfos(agentNo4List);
        Map<String, AgentInfoEntity> agentInfoEntityMap = agentInfos.stream().collect(Collectors.toMap(AgentInfoEntity::getAgentNo, item -> item));

        // 新增数据
        List<ActivityChannelEntity> addActivityChannelList = new ArrayList<>();
        // 结果数据
        List<ActivityChannelDTO.ActivityChannel> resultActivityChannelList = new ArrayList<>();
        // 导出数据
        List<String> exportChannelCodes = new ArrayList<>();

        // 判断商户还是其他渠道
        if (Constants.CHANNEL_TYPE.MERCHANT == activityChannelDTO.getChannelType()) {
            // 查询商户信息和查询商户所属机构
            List<MchInfoEntity> mchInfos = mchInfoService.list(MchInfoEntity.gw().in(MchInfoEntity::getMchNo, channelCodes));
            Map<String, String> mchAgentNoMap =
                    mchInfos.stream().
                            filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo()))
                            .collect(Collectors.toMap(MchInfoEntity::getMchNo, MchInfoEntity::getAgentNo));

            Map<String, MchInfoEntity> mchInfoMap =
                    mchInfos.stream().
                            filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo()))
                            .collect(Collectors.toMap(MchInfoEntity::getMchNo, item -> item));

            Map<String, String> agentNoMap = new HashMap<>();
            if (!mchAgentNoMap.isEmpty()) {
                List<AgentInfoEntity> agentInfoList = agentInfoService.listByIds(mchAgentNoMap.values());
                agentNoMap = switch (agentInfo.getLevel()) {
                    case 1 ->
                            agentInfoList.stream().collect(Collectors.toMap(AgentInfoEntity::getAgentNo, AgentInfoEntity::getAgentNo1));
                    case 2 ->
                            agentInfoList.stream().collect(Collectors.toMap(AgentInfoEntity::getAgentNo, AgentInfoEntity::getAgentNo2));
                    case 3 ->
                            agentInfoList.stream().collect(Collectors.toMap(AgentInfoEntity::getAgentNo, AgentInfoEntity::getAgentNo3));
                    case 4 ->
                            agentInfoList.stream().collect(Collectors.toMap(AgentInfoEntity::getAgentNo, AgentInfoEntity::getAgentNo4));
                    default -> agentNoMap;
                };
            }

            for (int i = 0; i < activityChannelToList.size(); i++) {
                    ActivityChannelDTO.ActivityChannel activityChannel = activityChannelToList.get(i);
                int total = activityChannelToList.size();
                if (!agentInfoEntityMap.containsKey(activityChannel.getAgentNo4())) {
                    activityChannel.setErrorMessage("导入机构网点信息有误，请排查！");
                    activityChannel.setErrType(2);
                    resultActivityChannelList.add(activityChannel);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total,"导入机构员工", "第" + (i + 1) + "行，导入机构网点信息有误，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }

                // 查询机构网点是否是所选网点的下属机构
                boolean flag = switch (agentInfo.getLevel()) {
                    case 1 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getAgentNo4()).getAgentNo1());
                    case 2 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getAgentNo4()).getAgentNo2());
                    case 3 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getAgentNo4()).getAgentNo3());
                    case 4 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getAgentNo4()).getAgentNo4());
                    default -> false;
                };
                if (!flag) {
                    activityChannel.setErrorMessage("所填机构网点号与所选机构号无从属关系");
                    activityChannel.setErrType(2);
                    resultActivityChannelList.add(activityChannel);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，所填机构网点号与所选机构号无从属关系，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }

                // 查询商户此商户是否存在
                if (!mchAgentNoMap.containsKey(activityChannel.getChannelCode())) {
                    activityChannel.setErrorMessage("商户不存在");
                    activityChannel.setErrType(2);
                    resultActivityChannelList.add(activityChannel);
                    //                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，商户不存在，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }
                // 查询商户信息和商户所属机构是否对应
                if (!activityChannel.getAgentNo4().equals(mchAgentNoMap.get(activityChannel.getChannelCode()))) {
                    activityChannel.setErrorMessage("商户不属于该机构");
                    activityChannel.setErrType(4);
                    resultActivityChannelList.add(activityChannel);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，商户不属于该机构，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }
                if (existChannelCodes.contains(activityChannel.getAgentNo4() + "-" + activityChannel.getChannelCode())) {
                    activityChannel.setErrorMessage("已存在渠道名单中");
                    activityChannel.setErrType(1);
//                    activityChannel.setAgentNo4(mchAgentNoMap.get(activityChannel.getChannelCode()));
                    resultActivityChannelList.add(activityChannel);
//                    exportChannelCodes.add(activityChannel.getChannelCode());
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，已存在渠道名单中，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }
                if (ObjectUtils.isEmpty(activityChannel.getIsDistanceLimit())
                        || ("是".equals(activityChannel.getIsDistanceLimit()) && null == activityChannel.getDistanceLimit())) {
                    activityChannel.setErrorMessage("未设置区域限制");
                    activityChannel.setErrType(3);
                    resultActivityChannelList.add(activityChannel);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，未设置区域限制，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }

                ActivityChannelEntity activityChannelEntity = new ActivityChannelEntity();
                BeanUtils.copyProperties(activityChannel, activityChannelEntity);
                activityChannelEntity.setChannelCode(activityChannel.getAgentNo4() + "-" + activityChannel.getChannelCode());
                activityChannelEntity.setChannelName(mchInfoMap.get(activityChannel.getChannelCode()).getMchName());
                activityChannelEntity.setOssRecordId(recordEntity.getOssRecordId());
                activityChannelEntity.setIsDeleted(Constants.IS_DELETED.NO);
                activityChannelEntity.setChannelType(activityChannelDTO.getChannelType());
                activityChannelEntity.setAppId(activityChannelDTO.getAppId());
                if ("是".equals(activityChannel.getIsDistanceLimit())) {
                    activityChannelEntity.setIsDistanceLimit(1);
                    activityChannelEntity.setDistanceLimit(activityChannel.getDistanceLimit());
                }
                addActivityChannelList.add(activityChannelEntity);
                // 添加结果
                activityChannel.setAgentNo4(mchAgentNoMap.get(activityChannel.getChannelCode()));
                activityChannel.setErrorMessage("新增成功");
                resultActivityChannelList.add(activityChannel);
                // 添加可导出商户号
                exportChannelCodes.add(activityChannel.getChannelCode());
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，新增成功！", WebSocketConstants.ImportStatus.SUCCESS);

            }

        } else if (Constants.CHANNEL_TYPE.ORG_EMPLOYEE == activityChannelDTO.getChannelType()) {
            for (int i = 0; i < activityChannelToList.size(); i++) {
                ActivityChannelDTO.ActivityChannel activityChannel = activityChannelToList.get(i);
                int total = activityChannelToList.size();

                // 查询所填的机构网点是否存在
                if (!agentInfoEntityMap.containsKey(activityChannel.getAgentNo4())) {
                    activityChannel.setErrorMessage("导入机构网点信息有误，请排查！");
                    activityChannel.setErrType(2);
                    resultActivityChannelList.add(activityChannel);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，导入机构网点信息有误，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }
                // 查询机构网点是否是所选网点的下属机构
                boolean flag = switch (agentInfo.getLevel()) {
                    case 1 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getAgentNo4()).getAgentNo1());
                    case 2 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getAgentNo4()).getAgentNo2());
                    case 3 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getAgentNo4()).getAgentNo3());
                    case 4 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getAgentNo4()).getAgentNo4());
                    default -> false;
                };
                if (!flag) {
                    activityChannel.setErrorMessage("所填机构网点号与所选机构号无从属关系");
                    activityChannel.setErrType(2);
                    resultActivityChannelList.add(activityChannel);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，所填机构网点号与所选机构号无从属关系，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }

                // 查询员工与所填机构是否有从属关系
                AgentEmployeeEntity agentEmployeeInfo =
                        agentEmployeeService.getAgentEmployeeInfo(activityChannel.getAgentNo4(), activityChannel.getChannelCode());

                // 机构员工
                if (ObjectUtils.isEmpty(agentEmployeeInfo)) {
                    activityChannel.setErrorMessage("机构与员工不对应");
                    activityChannel.setErrType(2);
                    resultActivityChannelList.add(activityChannel);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，机构与员工不对应，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }

                // 是否已在渠道名单中
                if (existChannelCodes.contains(activityChannel.getAgentNo4() + "-" + activityChannel.getChannelCode())) {
                    activityChannel.setErrorMessage("已存在渠道名单中");
                    activityChannel.setErrType(1);
                    resultActivityChannelList.add(activityChannel);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，已存在渠道名单中，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }
                ActivityChannelEntity activityChannelEntity = new ActivityChannelEntity();
                BeanUtils.copyProperties(activityChannel, activityChannelEntity);
                activityChannelEntity.setChannelCode(activityChannel.getAgentNo4() + "-" + activityChannel.getChannelCode());
                activityChannelEntity.setChannelName(agentEmployeeInfo.getEmployeeName());
                activityChannelEntity.setOssRecordId(recordEntity.getOssRecordId());
                activityChannelEntity.setIsDeleted(Constants.IS_DELETED.NO);
                activityChannelEntity.setChannelType(activityChannelDTO.getChannelType());
                activityChannelEntity.setAppId(activityChannelDTO.getAppId());
                addActivityChannelList.add(activityChannelEntity);
                // 添加结果
                activityChannel.setErrorMessage("新增成功");
                resultActivityChannelList.add(activityChannel);
                // 添加可导出商户号
                exportChannelCodes.add(activityChannel.getChannelCode());
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，新增成功！", WebSocketConstants.ImportStatus.SUCCESS);
            }
        } else {
            for (int i = 0; i < activityChannelToList.size(); i++) {
                ActivityChannelDTO.ActivityChannel activityChannel = activityChannelToList.get(i);
                int total = activityChannelToList.size();
                // 查询所填的机构网点(渠道)是否存在
                if (!agentInfoEntityMap.containsKey(activityChannel.getChannelCode())) {
                    activityChannel.setErrorMessage("导入机构网点信息有误，请排查！");
                    activityChannel.setErrType(2);
                    resultActivityChannelList.add(activityChannel);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，导入机构网点信息有误，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }
                // 查询机构网点是否是所选网点的下属机构
                boolean flag = switch (agentInfo.getLevel()) {
                    case 1 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getChannelCode()).getAgentNo1());
                    case 2 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getChannelCode()).getAgentNo2());
                    case 3 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getChannelCode()).getAgentNo3());
                    case 4 ->
                            activityChannelDTO.getAgentNo().equals(agentInfoEntityMap.get(activityChannel.getChannelCode()).getAgentNo4());
                    default -> false;
                };
                if (!flag) {
                    activityChannel.setErrorMessage("所填机构网点号与所选机构号无从属关系");
                    activityChannel.setErrType(2);
                    resultActivityChannelList.add(activityChannel);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，所填机构网点号与所选机构号无从属关系，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }
                // 是否已在渠道名单中
                if (existChannelCodes.contains(activityChannel.getChannelCode())) {
                    activityChannel.setErrorMessage("已存在渠道名单中");
                    activityChannel.setErrType(1);
//                    exportChannelCodes.add(activityChannel.getChannelCode());
                    resultActivityChannelList.add(activityChannel);
                    //                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，已存在渠道名单中，请排查！", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }

                ActivityChannelEntity activityChannelEntity = new ActivityChannelEntity();
                BeanUtils.copyProperties(activityChannel, activityChannelEntity);
                activityChannelEntity.setOssRecordId(recordEntity.getOssRecordId());
                activityChannelEntity.setIsDeleted(Constants.IS_DELETED.NO);
                activityChannelEntity.setChannelType(activityChannelDTO.getChannelType());
                activityChannelEntity.setAppId(activityChannelDTO.getAppId());
                activityChannelEntity.setChannelName(agentInfoEntityMap.get(activityChannel.getChannelCode()).getAgentName());
                addActivityChannelList.add(activityChannelEntity);
                // 添加结果
                activityChannel.setErrorMessage("新增成功");
                resultActivityChannelList.add(activityChannel);
                // 添加可导出code
                exportChannelCodes.add(activityChannel.getChannelCode());
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，新增成功！", WebSocketConstants.ImportStatus.SUCCESS);
            }
        }

        if (!addActivityChannelList.isEmpty()) {
            // 新增
            try {
                saveBatch(addActivityChannelList);
            } catch (Exception e) {
                e.getMessage();
                if (e instanceof DuplicateKeyException) {
                    throw new BizException("渠道编号重复");
                }
                throw new BizException("批量导入失败");
            }
        }
        log.info("新增渠道码 新增数据：{}", JSONUtil.toJsonStr(addActivityChannelList));

//        return addActivityChannelList.size();
        JSONObject json = new JSONObject();
        json.put("result", resultActivityChannelList);
        json.put("export", exportChannelCodes);
        log.info("新增渠道码 返回数据信息：{}", json.toJSONString());
        return json;
    }

    /**
     * 通过oss导入的文件获取数据
     *
     * @return
     */
    public List<ActivityChannelDTO.ActivityChannel> getActivityChannelToList(String ossFileUrl, Integer channelType, String bizType) {
        File file = FileUtil.file(String.format("./temp/%s.xlsx", DateUtil.date().getTime()));
        HttpUtil.downloadFile(ossFileUrl, file);

        OssRecordEntity recordEntity = ossRecordService.getBaseMapper().selectOne(
                OssRecordEntity.gw()
                        .eq(OssRecordEntity::getOssUrl, ossFileUrl)
                        .eq(OssRecordEntity::getUploadType, Constants.OSS_UPLOAD_TYPE.ACTIVITY_CHANNEL_IMPORT));
        if (null == recordEntity) {
            // 添加oos上传记录
            OssRecordEntity ossRecordEntity = new OssRecordEntity();
            ossRecordEntity.setBizType(bizType);
            ossRecordEntity.setOssUrl(ossFileUrl);
            ossRecordEntity.setFileSize(file.length());
            ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.ACTIVITY_CHANNEL_IMPORT);
            ossRecordEntity.setSysUserId(GzUserDetails.getCurrentUserDetails().getSysUser().getSysUserId());
            ossRecordEntity.setCreatedAt(new Date());
            ossRecordService.save(ossRecordEntity);
        } else {
            recordEntity.setOssUrl(ossFileUrl);
            ossRecordService.getBaseMapper().updateById(recordEntity);
        }
        // 读取文件内容
        ExcelReader reader = ExcelUtil.getReader(file);

        if (Constants.CHANNEL_TYPE.MERCHANT == channelType) {
            reader.addHeaderAlias("商户对应机构号", "agentNo4");
            reader.addHeaderAlias("商户号", "channelCode");
            reader.addHeaderAlias("是否开启距离限制", "isDistanceLimit");
            reader.addHeaderAlias("限制距离/米", "distanceLimit");
        } else if (Constants.CHANNEL_TYPE.ORG_EMPLOYEE == channelType) {
            reader.addHeaderAlias("机构网点号", "agentNo4");
            reader.addHeaderAlias("员工编号", "channelCode");
        } else if (Constants.CHANNEL_TYPE.ORG_NETWORK == channelType){
            reader.addHeaderAlias("机构网点号", "channelCode");
//            reader.addHeaderAlias("机构网点号", "agentNo4");
        } else if (Constants.CHANNEL_TYPE.SELF_BUILD == channelType) {
            reader.addHeaderAlias("归属网点机构号", "agentNo4");
            reader.addHeaderAlias("渠道码名称", "channelName");
            reader.addHeaderAlias("是否开启距离限制", "isDistanceLimit");
            reader.addHeaderAlias("限制距离（米）", "distanceLimit");
            reader.addHeaderAlias("经度", "longitude");
            reader.addHeaderAlias("纬度", "latitude");
            reader.addHeaderAlias("地址", "address");
        }
        List<ActivityChannelDTO.ActivityChannel> all = reader.readAll(ActivityChannelDTO.ActivityChannel.class);
        reader.close();
        FileUtil.del(file);
        return all;
    }

    /**
     * 新增单个渠道码
     *
     * @param activityChannelDTO
     * @return
     */
    public JSONObject addOne(ActivityChannelDTO activityChannelDTO) {

        // 渠道类型
        Integer channelType = activityChannelDTO.getChannelType();
        // 校验参数
        if (ObjectUtils.isEmpty(channelType) || ObjectUtils.isEmpty(activityChannelDTO.getChannelCode()) || StrUtil.isBlank(activityChannelDTO.getAppId())) {
            throw new BizException("请求参数异常，请检查！");
        }

        // 查询机构信息
        AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(activityChannelDTO.getAgentNo());
        if (ObjectUtils.isEmpty(agentInfo)) {
            throw new BizException("公众号归属机构不存在");
        }

        // 查询 机构app信息
        List<AgentAppVO> agentNoApp = agentAppService.getAgentNoApp(activityChannelDTO.getAgentNo(), Constants.AGENT_APP_TYPE.WX_OFFICIAL, activityChannelDTO.getAppId());
        if (ObjectUtils.isEmpty(agentNoApp)) {
            throw new BizException("该机构的公众号不存在");
        }

        // 新增后列表数据
        List<ActivityChannelDTO.ActivityChannel> resultActivityChannelList = new ArrayList<>();
        // 导出渠道码数据
        List<String> exportChannelCodes = new ArrayList<>();

        ActivityChannelDTO.ActivityChannel activityChannel = new ActivityChannelDTO.ActivityChannel();
        activityChannel.setChannelCode(activityChannelDTO.getChannelCode());
        activityChannel.setAgentNo4(activityChannelDTO.getAgentNo4());
        resultActivityChannelList.add(activityChannel);

        // 返回JSON结果
        JSONObject json = new JSONObject();
        json.put("result", resultActivityChannelList);
        json.put("export", exportChannelCodes);

        // 查询渠道码是否存在
        LambdaQueryWrapper<ActivityChannelEntity> queryWrapper = ActivityChannelEntity.gw();
        if (Constants.CHANNEL_TYPE.ORG_NETWORK != activityChannelDTO.getChannelType()) {
            queryWrapper.eq(ActivityChannelEntity::getChannelCode, activityChannelDTO.getAgentNo4() + "-" + activityChannelDTO.getChannelCode());
        } else {
            queryWrapper.eq(ActivityChannelEntity::getChannelCode, activityChannelDTO.getChannelCode());
        }
        queryWrapper.eq(ActivityChannelEntity::getIsDeleted, Constants.IS_DELETED.NO);
        queryWrapper.eq(ActivityChannelEntity::getChannelType, activityChannelDTO.getChannelType());
        queryWrapper.eq(ActivityChannelEntity::getAppId, activityChannelDTO.getAppId());
        ActivityChannelEntity activityChannelEntity = activityChannelMapper.selectOne(queryWrapper);

        // 不存在，新增
        if (ObjectUtils.isEmpty(activityChannelEntity)) {
            // 判断是商户渠道还是其他渠道
            if (Constants.CHANNEL_TYPE.MERCHANT == activityChannelDTO.getChannelType()) {
                AgentInfoEntity agentInfo4 = agentInfoService.getAgentInfo(activityChannelDTO.getAgentNo4());
                if (ObjectUtils.isEmpty(agentInfo4)) {
                    activityChannel.setErrorMessage("机构网点号不存在");
                    activityChannel.setErrType(2);
                    return json;
                }

                boolean flag = switch (agentInfo.getLevel()) {
                    case 1 -> activityChannelDTO.getAgentNo().equals(agentInfo4.getAgentNo1());
                    case 2 -> activityChannelDTO.getAgentNo().equals(agentInfo4.getAgentNo2());
                    case 3 -> activityChannelDTO.getAgentNo().equals(agentInfo4.getAgentNo3());
                    case 4 -> activityChannelDTO.getAgentNo().equals(agentInfo4.getAgentNo4());
                    default -> false;
                };

                if (!flag) {
                    activityChannel.setErrorMessage("机构网点号与公众号归属机构无从属关系");
                    activityChannel.setErrType(2);
                    return json;
                }

                // 查询商户信息
                MchInfoEntity mchInfo = mchInfoService.getById(activityChannelDTO.getChannelCode());
                if (ObjectUtils.isEmpty(mchInfo)) {
                    activityChannel.setErrorMessage("商户不存在");
                    activityChannel.setErrType(2);
                    return json;
                }

                if (!StringUtils.equals(activityChannelDTO.getAgentNo4(), mchInfo.getAgentNo())) {
                    activityChannel.setErrorMessage("商户不属于该机构");
                    activityChannel.setErrType(4);
                    return json;
                }

                // 判断是否设置距离限制
                if (ObjectUtils.isEmpty(activityChannelDTO.getIsDistanceLimit())
                        || (1 == activityChannelDTO.getIsDistanceLimit() && null == activityChannelDTO.getDistanceLimit())) {
                    activityChannel.setErrorMessage("未设置区域限制");
                    activityChannel.setErrType(3);
                    return json;
                }
                // 新增
                activityChannelDTO.setChannelCode(activityChannelDTO.getAgentNo4() + "-" + activityChannelDTO.getChannelCode());
                activityChannelDTO.setChannelName(mchInfo.getMchName());
                this.addActivityChannel(activityChannelDTO);
                // 添加结果
                activityChannel.setAgentNo4(mchInfo.getAgentNo());
                activityChannel.setErrorMessage("新增成功");
                // 添加可导出商户号
                exportChannelCodes.add(activityChannel.getChannelCode());
                return json;
            } else if (Constants.CHANNEL_TYPE.ORG_EMPLOYEE == activityChannelDTO.getChannelType()) {
                AgentInfoEntity agentInfo4 = agentInfoService.getAgentInfo(activityChannelDTO.getAgentNo4());
                if (ObjectUtils.isEmpty(agentInfo4)) {
                    activityChannel.setErrorMessage("机构网点不存在");
                    activityChannel.setErrType(2);
                    return json;
                }

                boolean flag = switch (agentInfo.getLevel()) {
                    case 1 -> activityChannelDTO.getAgentNo().equals(agentInfo4.getAgentNo1());
                    case 2 -> activityChannelDTO.getAgentNo().equals(agentInfo4.getAgentNo2());
                    case 3 -> activityChannelDTO.getAgentNo().equals(agentInfo4.getAgentNo3());
                    case 4 -> activityChannelDTO.getAgentNo().equals(agentInfo4.getAgentNo4());
                    default -> false;
                };

                if (!flag) {
                    activityChannel.setErrorMessage("机构号与公众号归属机构无从属关系");
                    activityChannel.setErrType(2);
                    return json;
                }

                AgentEmployeeEntity agentEmployeeInfo =
                        agentEmployeeService.getAgentEmployeeInfo(activityChannelDTO.getAgentNo4(), activityChannelDTO.getChannelCode());
                // 机构员工
                if (ObjectUtils.isEmpty(agentEmployeeInfo)) {
                    activityChannel.setErrorMessage("员工不属于该机构");
                    activityChannel.setErrType(2);
                    return json;
                }

                // 新增
                activityChannelDTO.setChannelCode(activityChannelDTO.getAgentNo4() + "-" + activityChannelDTO.getChannelCode());
                activityChannelDTO.setChannelName(agentEmployeeInfo.getEmployeeName());
                this.addActivityChannel(activityChannelDTO);
                // 添加结果
                activityChannel.setAgentNo4(activityChannelDTO.getAgentNo4());
                activityChannel.setErrorMessage("新增成功");
                // 添加可导出机构号
                exportChannelCodes.add(activityChannel.getChannelCode());
                return json;
            } else {
                // 查询机构网点是否存在
                AgentInfoEntity agentInfoOfNetwork = agentInfoService.getAgentInfo(activityChannelDTO.getChannelCode());
                if (ObjectUtils.isEmpty(agentInfoOfNetwork)) {
                    //不存在，返回
                    activityChannel.setErrorMessage("机构网点不存在");
                    activityChannel.setErrType(1);
                    return json;
                }

                boolean flag = switch (agentInfo.getLevel()) {
                    case 1 -> activityChannelDTO.getAgentNo().equals(agentInfoOfNetwork.getAgentNo1());
                    case 2 -> activityChannelDTO.getAgentNo().equals(agentInfoOfNetwork.getAgentNo2());
                    case 3 -> activityChannelDTO.getAgentNo().equals(agentInfoOfNetwork.getAgentNo3());
                    case 4 -> activityChannelDTO.getAgentNo().equals(agentInfoOfNetwork.getAgentNo4());
                    default -> false;
                };

                if (!flag) {
                    activityChannel.setErrorMessage("机构号与公众号归属机构无从属关系");
                    activityChannel.setErrType(2);
                    return json;
                }

                // 新增
                activityChannelDTO.setChannelName(agentInfoOfNetwork.getAgentName());
                this.addActivityChannel(activityChannelDTO);
                // 添加结果
                activityChannel.setAgentNo4(activityChannelDTO.getAgentNo4());
                activityChannel.setErrorMessage("新增成功");
                // 添加可导出code
                exportChannelCodes.add(activityChannel.getChannelCode());
                return json;
            }
        } else {
            //存在，返回
            activityChannel.setErrorMessage("已存在渠道名单中");
            activityChannel.setErrType(1);
            if (Constants.CHANNEL_TYPE.MERCHANT == activityChannelDTO.getChannelType()) {
                // 查询商户所属机构
                MchInfoEntity mchInfo = mchInfoService.getById(activityChannelDTO.getChannelCode());
                activityChannel.setAgentNo4(mchInfo.getAgentNo());
            } else {
                activityChannel.setAgentNo4(activityChannelDTO.getAgentNo4());
            }
            exportChannelCodes.add(activityChannel.getChannelCode());
            return json;
        }
    }

    /**
     * 新增渠道码
     *
     * @param activityChannelDTO
     */
    public void addActivityChannel(ActivityChannelDTO activityChannelDTO) {
        ActivityChannelEntity activityChannelEntity = new ActivityChannelEntity();
        BeanUtils.copyProperties(activityChannelDTO, activityChannelEntity);
        activityChannelEntity.setIsDeleted(Constants.IS_DELETED.NO);
        activityChannelEntity.setChannelType(activityChannelDTO.getChannelType());
        if (activityChannelDTO.getIsDistanceLimit() != null && 1 == activityChannelDTO.getIsDistanceLimit()) {
            activityChannelEntity.setIsDistanceLimit(1);
            activityChannelEntity.setDistanceLimit(activityChannelDTO.getDistanceLimit());
        }
        save(activityChannelEntity);
        log.info("新增渠道码 新增数据：{}", JSONUtil.toJsonStr(activityChannelEntity));
    }

    /**
     * 删除渠道码
     *
     * @param activityChannelId 渠道码ID
     * @param isDeleted         是否删除
     * @return
     */
    public void deleteChannelById(Long activityChannelId, Integer isDeleted) {
        if (Objects.isNull(activityChannelId) || Objects.isNull(isDeleted)) {
            throw new BizException("请求参数缺失！");
        }
        ActivityChannelEntity dto = new ActivityChannelEntity();
        dto.setActivityChannelId(activityChannelId);
        dto.setIsDeleted(isDeleted);
        boolean flag = updateById(dto);
        if (!flag) {
            throw new BizException("删除渠道码失败！");
        }
    }

    /**
     * 更新渠道码距离限制
     *
     * @param activityChannelId 渠道码ID
     * @param isDistanceLimit   是否限制
     * @param distanceLimit     限制距离
     * @return
     */
    public void updateDistanceLimit(Long activityChannelId, Integer isDistanceLimit, Float distanceLimit) {
        if (Objects.isNull(activityChannelId) || Objects.isNull(isDistanceLimit)) {
            throw new BizException("请求参数缺失！");
        }
        if (1 == isDistanceLimit && ObjectUtils.isEmpty(distanceLimit)) {
            throw new BizException("请求参数缺失！");
        }
        ActivityChannelEntity dto = new ActivityChannelEntity();
        dto.setActivityChannelId(activityChannelId);
        dto.setIsDistanceLimit(isDistanceLimit);
        if (1 == isDistanceLimit) {
            dto.setDistanceLimit(distanceLimit);
        }
        boolean flag = updateById(dto);
        if (!flag) {
            throw new BizException("更新渠道码距离失败！");
        }
    }

    public ActivityChannelEntity findActivityImgUrlByActivityId(Long channelId) {
        // 判断是否过期
        ActivityChannelEntity channelEntity = activityChannelMapper.selectById(channelId);
        log.info("活动海报渠道码信息：{}", JSON.toJSONString(channelEntity));
        if (Objects.isNull(channelEntity)) {
            log.info("未配置该活动渠道信息：渠道id：{}", channelId);
            return null;
        } else {
            List<ActivityEntity> list = activityService.selectActivityListByChannelType(channelEntity.getChannelCode(), channelEntity.getChannelType());
            AgentAppEntity agentAppEntity = agentAppService.getOne(
                    AgentAppEntity.gw()
                            .eq(AgentAppEntity::getAppId, channelEntity.getAppId())
                            .eq(AgentAppEntity::getType, 0)
            );
            log.info("公众号配置信息：{}", JSON.toJSONString(agentAppEntity));
            JSONObject json = new JSONObject();
            if (null != list && list.size() > 0) {
                json.put("activityNum", list.size());
                String actvityId = String.valueOf(list.get(0).getActivityId());
                json.put("activityId", actvityId);
            }
            log.info("渠道永久码存储json数据：{}", JSONUtil.toJsonStr(json));
            if (StringUtils.isEmpty(channelEntity.getUrl())) {
                log.info("首次生成渠道永久码channelId: {}", channelId);
                //活动渠道表中没有Url 生成微信公众号临时码
                generateWXUrl(channelEntity, agentAppEntity, json);
            } else {
                if (DateUtil.current() > channelEntity.getExpireTime().getTime()) {
                    log.info("渠道永久码channelId已生效，重新生成：{}", channelId);
                    //活动渠道表中有Url，公众号临时码过期，生成微信公众号临时码
                    generateWXUrl(channelEntity, agentAppEntity, json);
                }
            }
        }
        return activityChannelMapper.selectById(channelId);
    }

    private void generateWXUrl(ActivityChannelEntity channelEntity, AgentAppEntity agentAppEntity, JSONObject json) {
        json.put("channelCode", channelEntity.getChannelCode());
        json.put("channelType", channelEntity.getChannelType());
        json.put("channelId", channelEntity.getActivityChannelId());
        if (Objects.isNull(agentAppEntity)) {
            throw new BizException("地域公众号配置信息错误!");
        }

        log.info("生成Url请求json数据：{}", JSONUtil.toJsonStr(json));
        String decode = officialService.qrCodeCreateTmpTicket(json, agentAppEntity.getAppId(), setWxService(agentAppEntity.getAppId()));
        if (StringUtils.isNotEmpty(decode)) {
            JSONObject object = JSONObject.parseObject(decode);
            ActivityChannelEntity dto = new ActivityChannelEntity();
            dto.setUrl(object.getString("url"));
            dto.setTicket(object.getString("ticket"));
            dto.setActivityChannelId(channelEntity.getActivityChannelId());
            dto.setCreatedAt(new Date());
            dto.setExpireTime(DateUtil.offsetDay(new Date(), 30));
            log.info("更新活动渠道表信息：{}", JSONUtil.toJsonStr(dto));
            activityChannelMapper.updateById(dto);
        } else {
            throw new BizException("公众号生成二维码异常！");
        }
    }

    public WxMpService setWxService(String appid) {
        List<WxMpProperties.MpConfig> configs = new ArrayList<>();
        if (configs == null || configs.size() == 0) {
            BaseAgentApp agentApp = agentAppService.getAgentApp(appid);
            WxMpProperties.MpConfig mpConfig = new WxMpProperties.MpConfig();
            mpConfig.setAppId(appid);
            mpConfig.setSecret(agentApp.getAppSecret());
            mpConfig.setToken(agentApp.getToken());
            mpConfig.setAesKey(agentApp.getAesKey());
            configs.add(mpConfig);
        }
        log.info("公众号配置参数信息：{}", JSON.toJSONString(configs));
        WxMpService service = new WxMpServiceImpl();
        service.setMultiConfigStorages(configs
                .stream().map(a -> {
                    WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
                    configStorage.setAppId(a.getAppId());
                    configStorage.setSecret(a.getSecret());
                    configStorage.setToken(a.getToken());
                    configStorage.setAesKey(a.getAesKey());
                    configStorage.setUseStableAccessToken(true);
                    log.info("公众号发送消息时，相关配置信息（包括获取稳定版的token）：{}", JSON.toJSONString(configStorage));
                    return configStorage;
                }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
        return service;
    }

    public ActivityChannelEntity addOneSelfBuild(ActivityChannelDTO activityChannelDTO) {
        if (StrUtil.isBlank(activityChannelDTO.getAgentNo4()) || StrUtil.isBlank(activityChannelDTO.getChannelName())
                || ObjectUtils.isEmpty(activityChannelDTO.getLocation()) || StrUtil.isBlank(activityChannelDTO.getAddress())){
            throw new BizException("请求参数异常");
        }
        if (activityChannelDTO.getIsDistanceLimit() != null && activityChannelDTO.getDistanceLimit() == null) {
            throw new BizException("请求参数异常");
        }
        String agentNo4 = activityChannelDTO.getAgentNo4();
        AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(agentNo4);
        if (agentInfo == null || agentInfo.getLevel() != 4) {
            throw new BizException("机构不存在或不是网点机构");
        }
        //是否已存在
        List<ActivityChannelEntity> exist = list(ActivityChannelEntity.gw()
                .eq(ActivityChannelEntity::getAppId, activityChannelDTO.getAppId())
                .likeRight(ActivityChannelEntity::getChannelCode, agentNo4));
        if (!exist.isEmpty()) {
            throw new BizException("该网点已存在自建渠道");
        }
        ActivityChannelEntity channelEntity = BeanUtil.copyProperties(activityChannelDTO, ActivityChannelEntity.class);
        channelEntity.setChannelCode(activityChannelDTO.getAgentNo4() + "-" + Utils.generateChannelCode());
        cn.hutool.json.JSONObject locationObj = JSONUtil.parseObj(activityChannelDTO.getLocation());
        locationObj.set("address", activityChannelDTO.getAddress());
        locationObj.set("areaCode", activityChannelDTO.getAreaCode());
        locationObj.set("areaName", activityChannelDTO.getAreaName());
        channelEntity.setRemark(JSONUtil.toJsonStr(locationObj));
        channelEntity.setChannelType(Constants.CHANNEL_TYPE.SELF_BUILD);
        save(channelEntity);
        return channelEntity;
    }

    /**
     * 获取自建渠道列表
     * @param iPage
     * @param activityChannelDTO
     * @return
     */
    public IPage<ActivityChannelVO> getSelfBuildChannelList(IPage iPage, ActivityChannelDTO activityChannelDTO) {

        IPage<ActivityChannelVO> channelList = baseMapper.getSelfBuildChannelList(iPage, activityChannelDTO);
        for (ActivityChannelVO record : channelList.getRecords()) {
            cn.hutool.json.JSONObject remarkObj = JSONUtil.parseObj(record.getRemark());
            record.setLongitude(remarkObj.getStr("longitude"));
            record.setLatitude(remarkObj.getStr("latitude"));
            record.setAddress(remarkObj.getStr("address"));
            record.setAreaCode(remarkObj.getStr("areaCode"));
            record.setAreaName(remarkObj.getStr("areaName"));
        }
        return channelList;
    }

    @Transactional(rollbackFor = Exception.class)
    public JSONObject importSelfBuildFile(ActivityChannelDTO activityChannelDTO) {
        // 校验参数
        if (StrUtil.isBlank(activityChannelDTO.getOssFileUrl()) || StrUtil.isBlank(activityChannelDTO.getAppId())) {
            throw new BizException("请求参数异常，请检查！");
        }
//        // 查询机构信息
//        AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(activityChannelDTO.getAgentNo());
//        if (ObjectUtils.isEmpty(agentInfo)) {
//            throw new BizException("公众号归属机构不存在");
//        }

        // 查询 机构app信息
//        List<AgentAppVO> agentNoApp = agentAppService.getAgentNoApp(activityChannelDTO.getAgentNo(),
//                Constants.AGENT_APP_TYPE.WX_OFFICIAL, activityChannelDTO.getAppId());
//        if (ObjectUtils.isEmpty(agentNoApp)) {
//            throw new BizException("该机构的公众号不存在");
//        }

        // 获取文件导入的渠道信息
        List<ActivityChannelDTO.ActivityChannel> activityChannelToList = getActivityChannelToList(activityChannelDTO.getOssFileUrl(),
                Constants.CHANNEL_TYPE.SELF_BUILD, OssFileConfig.BIZ_TYPE.UPLOAD);
        log.info("新增渠道码导入文件数据：{}", JSONUtil.toJsonStr(activityChannelToList));
        if (CollUtil.isEmpty(activityChannelToList)) {
            throw new BizException("导入渠道码数据为空");
        }

        // 查询oss上传记录
        LambdaQueryWrapper<OssRecordEntity> ossRecordWrapper = OssRecordEntity.gw();
        ossRecordWrapper.eq(OssRecordEntity::getOssUrl, activityChannelDTO.getOssFileUrl());
        ossRecordWrapper.eq(OssRecordEntity::getUploadType, Constants.OSS_UPLOAD_TYPE.ACTIVITY_CHANNEL_IMPORT);
        OssRecordEntity recordEntity = ossRecordService.getBaseMapper().selectOne(ossRecordWrapper);
        if (Objects.isNull(recordEntity)) {
            throw new BizException("导入失败！未找到，导入文件");
        }
        // 导入的归属网点机构号集
        List<String> agentNo4List = activityChannelToList.stream().map(ActivityChannelDTO.ActivityChannel::getAgentNo4).toList();
        // 查询所填的机构网点是否存在
        List<AgentInfoEntity> agentInfos = this.agentInfoService.getAgentInfos(agentNo4List);
        Map<String, AgentInfoEntity> agentInfoEntityMap = agentInfos.stream().collect(Collectors.toMap(AgentInfoEntity::getAgentNo, item -> item));

        //查询当前公众号下已经存在的自建渠道码
        List<ActivityChannelEntity> existChannel = this.list(ActivityChannelEntity.gw()
                .eq(ActivityChannelEntity::getAppId, activityChannelDTO.getAppId()));
        List<String> channelCodeList = new ArrayList<>();
        if (CollUtil.isNotEmpty(existChannel)) {
            channelCodeList = existChannel.stream().map(ActivityChannelEntity::getChannelCode).toList();
        }
        int successCount = 0;
        int failCount = 0;
        List<JSONObject> reasonObjects = new ArrayList<>();
        List<ActivityChannelEntity> channelEntityList = new ArrayList<>();
        ActivityChannelEntity channelEntity = null;
//        for (ActivityChannelDTO.ActivityChannel activityChannel : activityChannelToList) {
        for (int i = 0; i < activityChannelToList.size(); i++) {
            ActivityChannelDTO.ActivityChannel activityChannel = activityChannelToList.get(i);
            int total = activityChannelToList.size();

            JSONObject reasonObject = new JSONObject();
            reasonObject.put("agentNo4", activityChannel.getAgentNo4());
            reasonObject.put("channelName", activityChannel.getChannelName());
            reasonObject.put("isDistanceLimit", activityChannel.getIsDistanceLimit());
            reasonObject.put("distanceLimit", activityChannel.getDistanceLimit());
            reasonObject.put("longitude", activityChannel.getLongitude());
            reasonObject.put("latitude", activityChannel.getLatitude());
            reasonObject.put("address", activityChannel.getAddress());

            //归属网点机构号
            String agentNo4 = activityChannel.getAgentNo4();
            if (StrUtil.isBlank(agentNo4)) {
                failCount++;
                reasonObject.put("result", "归属网点机构号不能为空");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，归属网点机构号不能为空，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            if (!agentInfoEntityMap.containsKey(agentNo4) || agentInfoEntityMap.get(agentNo4).getLevel() != 4) {
                failCount++;
                reasonObject.put("result", "归属网点机构号不存在");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，归属网点机构号不存在或不为四级网点机构，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            if (!channelCodeList.isEmpty() && isOrgExist(channelCodeList, agentNo4)) {
                failCount++;
                reasonObject.put("result", "归属网点机构号已存在自建渠道码");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，归属网点机构号已存在自建渠道码，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            //TODO: 机构号是否本机构下属机构网点号
            //渠道码名称
            String channelName = activityChannel.getChannelName();
            if (StrUtil.isBlank(channelName)) {
                failCount++;
                reasonObject.put("result", "渠道码名称不能为空");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，渠道码名称不能为空，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            //是否开启距离限制
            String isDistanceLimit = activityChannel.getIsDistanceLimit();
            if (StrUtil.isBlank(isDistanceLimit)) {
                failCount++;
                reasonObject.put("result", "是否开启距离限制不能为空");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，是否开启距离限制不能为空，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            Float distanceLimit = activityChannel.getDistanceLimit();
            if ("是".equals(isDistanceLimit) && Objects.isNull(distanceLimit)) {
                failCount++;
                reasonObject.put("result", "限制距离未填写");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，限制距离未填写，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            //经纬度
            String longitude = activityChannel.getLongitude();
            if (StrUtil.isBlank(longitude)) {
                failCount++;
                reasonObject.put("result", "经度不能为空");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，经度不能为空，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            String latitude = activityChannel.getLatitude();
            if (StrUtil.isBlank(latitude)) {
                failCount++;
                reasonObject.put("result", "纬度不能为空");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，纬度不能为空，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            if (!GeoValidator.isValidFormat(latitude, longitude)) {
                failCount++;
                reasonObject.put("result", "经纬度格式错误");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，经纬度格式错误，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            if (!GeoValidator.isInChina(latitude, longitude)) {
                failCount++;
                reasonObject.put("result", "经纬度不在中国");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，经纬度不在中国，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            //地址
            String address = activityChannel.getAddress();
            if (StrUtil.isBlank(address)) {
                failCount++;
                reasonObject.put("result", "地址不能为空");
                reasonObjects.add(reasonObject);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，地址不能为空，请排查！", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            channelEntity = new ActivityChannelEntity();
            channelEntity.setAppId(activityChannelDTO.getAppId())
                    .setChannelCode(agentNo4 + "-" + Utils.generateChannelCode())
                    .setChannelName(channelName)
                    .setChannelType(Constants.CHANNEL_TYPE.SELF_BUILD)
                    .setIsDistanceLimit("是".equals(isDistanceLimit) ? 1 : 0)
                    .setDistanceLimit(distanceLimit);
            JSONObject remarkObj = new JSONObject();
            remarkObj.put("longitude", longitude);
            remarkObj.put("latitude", latitude);
            remarkObj.put("address", address);
            channelEntity.setRemark(remarkObj.toJSONString());
            channelEntityList.add(channelEntity);
            successCount++;
            reasonObject.put("result", "成功");
            reasonObjects.add(reasonObject);
//            wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入机构员工", "第" + (i + 1) + "行，新增成功！", WebSocketConstants.ImportStatus.SUCCESS);

        }
        if (CollUtil.isNotEmpty(channelEntityList)) {
            this.saveBatch(channelEntityList);
        }
//        return channelEntityList.size();
        JSONObject result = new JSONObject();
        result.put("successCount", successCount);
        result.put("failCount", failCount);
        result.put("reasonUrl", failOssUrl(reasonObjects));
        return result;
    }

    public String failOssUrl(List<JSONObject> jsonObjects) {
        if (jsonObjects.isEmpty()) {
            return "";
        }
        String failUrl = "";
        String successFileName = String.format("./temp/normal/fail/%s%s.xlsx", DateUtil.date().getTime(), "normal");
        File normalFile = new File(successFileName);
        ExcelWriter successWriter = ExcelUtil.getWriter(normalFile);
        successWriter.addHeaderAlias("agentNo4", "归属网点机构号");
        successWriter.addHeaderAlias("channelName", "渠道码名称");
        successWriter.addHeaderAlias("isDistanceLimit", "是否开启距离限制");
        successWriter.addHeaderAlias("distanceLimit", "距离限制（米）");
        successWriter.addHeaderAlias("longitude", "经度");
        successWriter.addHeaderAlias("latitude", "纬度");
        successWriter.addHeaderAlias("address", "地址");
        successWriter.addHeaderAlias("result", "结果");
        try {
            successWriter.write(jsonObjects);
            successWriter.close();
            MultipartFile multipartFile = new MockMultipartFile(successFileName, normalFile.length(), new FileInputStream(normalFile));
            failUrl = ossFileService.singleFileUpload(multipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
            // 添加oos上传记录
            OssRecordEntity ossRecordEntity = new OssRecordEntity();
            ossRecordEntity.setBizType(OssFileConfig.BIZ_TYPE.DOWNLOAD);
            ossRecordEntity.setOssUrl(failUrl);
            ossRecordEntity.setFileSize(normalFile.length());
            ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.SELF_BUILD_CHANNEL_IMPORT);
            ossRecordEntity.setCreatedAt(new Date());
            ossRecordService.save(ossRecordEntity);
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
        return failUrl;
    }

    private boolean isOrgExist(List<String> orgTimeList, String orgCode) {
        return orgTimeList.stream().anyMatch(s -> s.startsWith(orgCode));
    }


    /**
     * 获取渠道详情
     *
     * @param activityChannelDTO
     * @return
     */
    public ActivityChannelVO getSelfBuildChannelDetail(ActivityChannelDTO activityChannelDTO) {
        if (activityChannelDTO.getActivityChannelId() == null) {
            throw new BizException("参数错误");
        }
        ActivityChannelEntity channelEntity = this.getById(activityChannelDTO.getActivityChannelId());
        if (channelEntity == null) {
            throw new BizException("无当前渠道");
        }
        ActivityChannelVO activityChannelVO = BeanUtil.copyProperties(channelEntity, ActivityChannelVO.class);
        cn.hutool.json.JSONObject remarkObj = JSONUtil.parseObj(channelEntity.getRemark());
        activityChannelVO.setLongitude(remarkObj.getStr("longitude"))
                .setLatitude(remarkObj.getStr("latitude"))
                .setAddress(remarkObj.getStr("address"))
                .setAreaCode(remarkObj.getStr("areaCode"))
                .setAreaName(remarkObj.getStr("areaName"))
                .setAgentNo4(channelEntity.getChannelCode().substring(0, 8));
        return activityChannelVO;
    }

    /**
     * 修改渠道
     *
     * @param activityChannelDTO
     */
    public void updateSelfBuildChannel(ActivityChannelDTO activityChannelDTO) {
        if (activityChannelDTO.getActivityChannelId() == null) {
            throw new BizException("参数错误");
        }
        ActivityChannelEntity channelEntity = this.getById(activityChannelDTO.getActivityChannelId());
        if (channelEntity == null) {
            throw new BizException("无当前渠道");
        }
        BeanUtil.copyProperties(activityChannelDTO, channelEntity);
        cn.hutool.json.JSONObject locationObj = JSONUtil.parseObj(activityChannelDTO.getLocation());
        locationObj.set("address", activityChannelDTO.getAddress());
        locationObj.set("areaCode", activityChannelDTO.getAreaCode());
        locationObj.set("areaName", activityChannelDTO.getAreaName());
        channelEntity.setRemark(JSONUtil.toJsonStr(locationObj));
        this.updateById(channelEntity);
    }

    public void updateSelfBuildChannelStatus(Long activityChannelId, Integer isDeleted) {
        if (activityChannelId == null || isDeleted == null) {
            throw new BizException("请求参数缺失");
        }
        ActivityChannelEntity channelEntity = this.getById(activityChannelId);
        if (channelEntity == null) {
            throw new BizException("无当前渠道");
        }
        channelEntity.setIsDeleted(isDeleted);
        this.updateById(channelEntity);
    }

    public List<ActivityChannelVO> exportSelfBuildChannel(ActivityChannelDTO activityChannelDTO) {
        List<ActivityChannelVO> buildChannelList = baseMapper.getSelfBuildChannelList(activityChannelDTO);
        return buildChannelList;
    }

    public String exportSelfBuildChannelList(ActivityChannelDTO activityChannelDTO) {

        List<ActivityChannelVO> activityChannelVOS = exportSelfBuildChannel(activityChannelDTO);
        if (activityChannelVOS.isEmpty()) {
            throw new BizException("无自建渠道码信息");
        }

        for (ActivityChannelVO channelVO : activityChannelVOS) {
            channelVO.setIsDistanceLimitVal(channelVO.getIsDistanceLimit() == 1 ? "是" : "否");
            cn.hutool.json.JSONObject remarkObj = JSONUtil.parseObj(channelVO.getRemark());
            channelVO.setLongitude(remarkObj.getStr("longitude"));
            channelVO.setLatitude(remarkObj.getStr("latitude"));
            channelVO.setAddress(remarkObj.getStr("address"));
        }

        String successFileName = String.format("./temp/channelCode/%s.xlsx", DateUtil.date().getTime());

        File successFile = new File(successFileName);
        BigExcelWriter writer = ExcelUtil.getBigWriter(successFile);
        writer.renameSheet("自建渠道码列表信息");
        writer.addHeaderAlias("agentNo", "渠道码归属网点编号");
        writer.addHeaderAlias("agentName", "渠道码归属网点名称");
        writer.addHeaderAlias("agentNo3", "渠道码归属区县编号");
        writer.addHeaderAlias("agentName3", "渠道码归属区县名称");
        writer.addHeaderAlias("channelCode", "渠道码编号");
        writer.addHeaderAlias("channelName", "渠道码名称");
        writer.addHeaderAlias("isDistanceLimitVal", "是否开启距离限制");
        writer.addHeaderAlias("distanceLimit", "距离限制");
        writer.addHeaderAlias("address", "渠道码地址");
        writer.addHeaderAlias("longitude", "经度");
        writer.addHeaderAlias("latitude", "纬度");
        // 设置只使用别名，确保数据正确写入指定列
        writer.setOnlyAlias(true);
        // 写入数据列表到Excel
        writer.write(activityChannelVOS);
        //自动调整 Excel 文件中所有列的宽度
        writer.autoSizeColumnAll();
        // 关闭writer，释放资源
        writer.close();
        try {
            MultipartFile multipartFile = new MockMultipartFile(successFileName, successFile.length(), new FileInputStream(successFile));
            String successUrl = ossFileService.singleFileUpload(multipartFile, OssFileConfig.BIZ_TYPE.UPLOAD);
            // 添加oos上传记录
            OssRecordEntity ossRecordEntity = new OssRecordEntity();
            ossRecordEntity.setBizType(OssFileConfig.BIZ_TYPE.UPLOAD);
            ossRecordEntity.setOssUrl(successUrl);
            ossRecordEntity.setFileSize(successFile.length());
            ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.SELF_BUILD_CHANNEL_EXPORT);
            ossRecordEntity.setCreatedAt(new Date());
            ossRecordService.save(ossRecordEntity);
            return successUrl;
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }

    }
}
